package com.soho.controller;

import java.io.IOException;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Record;
import com.soho.helper.PrintHelper;
import com.soho.helper.UtilsHelper;

import online.mtapi.mt4.QuoteEventArgs;

@ServerEndpoint(value = "/socket.ws")
public class ApiWebsocket {

	private static final Map<String, Session> userSocketSessionMap = new ConcurrentHashMap<>();
	private static final Map<String,List<String>>	userSymbols= new ConcurrentHashMap<>();
	
	/**
	 * 给单个用户发送消息
	 */
	public void sendMsg(String userId, String message) {
		try {
			Session session = userSocketSessionMap.get(userId);
			if (session != null && session.isOpen()) {
				session.getAsyncRemote().sendText(JSON.toJSONString(message));
			}
		} catch (Exception e) {
			PrintHelper.print("WebSocket:用户[" + userId + "]发送消息异常", e);
		}
	}
	
	
	public static void sendMsg(QuoteEventArgs args) {
		for (Entry<String, Session> entry : userSocketSessionMap.entrySet()) {
			String account	=	entry.getKey();
			Session userSession=entry.getValue();
			if (userSession != null && userSession.isOpen()) {
				if(checkSubSymbol(account,args.Symbol)) {
					Record rc=new Record().set("Ask", args.Ask).set("Bid", args.Bid).set("Symbol", args.Symbol).set("Time", args.Time.toEpochSecond(ZoneOffset.UTC));
					userSession.getAsyncRemote().sendText(JsonKit.toJson(rc));
				}
			}
		}
	}

	/**
	 * 接收消息和回复消息
	 * 
	 * @param message
	 * @param session
	 */
	@OnMessage
	public void message(String message, Session session) {
		receiveSubscri(message,session);
	}
	
	private static boolean checkSubSymbol(String account,String symbol) {
		return userSymbols.get(account).contains(symbol);
	}
	private void receiveSubscri(String message,Session session) {
		JSONObject obj = JSON.parseObject(message);
		String account = obj.getString("Account");
		
		userSocketSessionMap.put(account, session);
		
		JSONArray quoteList = obj.getJSONObject("Quote").getJSONArray("List");
		
		List<String> bindSymbol	=	new ArrayList<>();
		int size= quoteList.size();
		for(int i=0;i<size;i++) {
			String symbol=quoteList.getJSONObject(i).getString("Symbol");
			if(UtilsHelper.checkIsEmpty(symbol)) {
				continue;
			}
			bindSymbol.add(symbol);
		}
		userSymbols.put(account, bindSymbol);
	}

	@OnOpen
	public void onOpen(Session session, EndpointConfig config) {
//		PrintHelper.print(session);
//		session.getAsyncRemote().sendText("Hello");
	}

	@OnClose
	public void onClose(Session session) throws Exception {
		PrintHelper.print("WebSocket: " + session.getId() + "已经关闭");
		Iterator<Entry<String, Session>> it = userSocketSessionMap.entrySet().iterator();
		// 移除Socket会话
		while (it.hasNext()) {
			Entry<String, Session> entry = it.next();
			if (entry.getValue().getId().equals(session.getId())) {
				userSocketSessionMap.remove(entry.getKey());
				PrintHelper.print("WebSocket会话已经移除:用户ID " + entry.getKey());
				break;
			}
		}
	}

	@OnError
	public void onError(Session session, Throwable error) throws IOException {
		if (session.isOpen()) {
			session.close();
		}
		Iterator<Entry<String, Session>> it = userSocketSessionMap.entrySet().iterator();
		// 移除Socket会话
		while (it.hasNext()) {
			Entry<String, Session> entry = it.next();
			if (entry.getValue().getId().equals(session.getId())) {
				userSocketSessionMap.remove(entry.getKey());
				PrintHelper.print("WebSocket会话已经移除:用户ID " + entry.getKey());
				break;
			}
		}
	}
}
